package com.vt.admin.service;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vt.admin.api.entity.SysSocialDetails;
import com.vt.admin.api.entity.SysUser;
import com.vt.admin.mapper.SysSocialDetailsMapper;
import com.vt.admin.mapper.SysUserMapper;
import com.vt.common.core.constant.SecurityConstants;
import com.vt.common.core.constant.enums.EnumLoginType;
import com.vt.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: panZha
 * @Date: 2018/11/20 14:26
 * @Description:
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysSocialDetailsService extends ServiceImpl<SysSocialDetailsMapper, SysSocialDetails> {

    private final CacheManager cacheManager;
    private final RestTemplate restTemplate;
    private final SysUserMapper sysUserMapper;

    public Map<String, String> findOpenId(String inStr) {
        String[] ss = inStr.split("@");

        //clientKey to openId
        SysSocialDetails social = getByClientKey(ss[0]);
        if (null == social)
            return null;

        return getOpenId(social.getAppId(), ss[1]);
    }

    public Boolean bindSocial(String clientKey, String code) {
        //clientKey to openId
        SysSocialDetails social = getByClientKey(clientKey);
        if (null == social)
            return null;

        Map<String, String> result = getOpenId(social.getAppId(), code);

        SysUser sysUser = sysUserMapper.selectById(SecurityUtils.getUser().getId());
        sysUser.setWxOpenId(result.get("openId"));

        sysUserMapper.updateById(sysUser);
        //更新缓存
        cacheManager.getCache("user_details").evict(result.get("openId"));
        return Boolean.TRUE;
    }

    private SysSocialDetails getByClientKey(String clientKey) {
        //clientKey to openId
        SysSocialDetails social = new SysSocialDetails().setClient(clientKey);
        social = this.baseMapper.selectOne(new QueryWrapper(social));
        if (null == social)
            return null;
        return social;
    }

    /**
     * 通过appid 、code 获得openID
     *
     * @param appId
     * @param code
     * @return
     */
    private Map<String, String> getOpenId(String appId, String code) {
        SysSocialDetails condition = new SysSocialDetails();
        condition.setAppId(appId);
        SysSocialDetails socialDetails = this.baseMapper.selectOne(new QueryWrapper(condition));

        String openId = null;
        //微信登录
        if (EnumLoginType.WECHAT.getType().equals(socialDetails.getType())) {
            String url = String.format(SecurityConstants.WX_AUTHORIZATION_CODE_URL
                    , socialDetails.getAppId(), socialDetails.getAppSecret(), code);
            String result = restTemplate.getForObject(url, String.class);
            log.debug("微信响应报文:{}", result);

            Object obj = JSONUtil.parseObj(result).get("openid");
            if (obj == null) {
                return null;
            }
            openId = obj.toString();
        }

        Map<String, String> result = new HashMap<>(2);
        result.put("type", socialDetails.getType());
        result.put("openId", openId);
        return result;
    }

    public Boolean unbindSocial() {
        SysUser user = sysUserMapper.selectById(SecurityUtils.getUser().getId());

        cacheManager.getCache("user_details").evict(user.getWxOpenId());
        this.sysUserMapper.unbindSocial(user.getId());
        return true;
    }
}
